home *** CD-ROM | disk | FTP | other *** search
- UNIT adp_mod;
-
- {$O+}
-
- { ------------------------------------------------------------------
-
- This program and its associates implement in Turbo Pascal v5
- the aritmetic encoding/decoding algorithms presented in the papers
-
- "Arithmetic Coding for Data Compression"
-
- by Ian H. Witten
- Radford M. Neal
- John G. Cleary
-
- pp 520 - 540 of June 1987 Communications of the ACM
-
- and
-
- "An Adaptive Dependency Source Model For Data Compression"
-
- by David M. Abrahamson
-
- pp 77 - 83 of January 1989 Communications of the ACM
-
- ------------------------------------------------------------------
-
- Implemented by Ken Westerback : CompuServe 73547,3520
-
- version 1.0 released 89/02/19
- version 2.0 released 89/02/27
-
- These programs, units and associated documentation are released
- into the public domain to be used and abused as your whims
- dictate.
-
- Feel free to distribute/incorporate/improve as desired.
-
- >>>>> Use at your own risk! <<<<<
-
- Comments and suggestions welcome via CompuServe.
-
- ------------------------------------------------------------------
- }
-
- interface
-
-
- const model_name = 'Adaptive Dependency Source Model';
-
-
- { this procedure initializes the model - must be exported cuz we }
- { may be overlay'ed }
-
- procedure start_model;
-
- function select_symbol ( ch : char ) : integer;
-
- function select_char ( symbol : integer ) : char;
-
- procedure update_model ( symbol : integer );
-
-
- implementation uses model_h;
-
- const max_count = 65535; { 2**16 - 1 }
-
- type symbol_array = array [ 0..no_of_symbols ] of char;
- char_array = array [ 0..no_of_chars-1 ] of integer;
- count_array = array [ 0..no_of_symbols ] of 0..max_count;
- ctoi_array = array[ 0..no_of_chars-1 ] of ^char_array;
- itoc_array = array[ 0..no_of_chars-1 ] of ^symbol_array;
- ctoi_p = ^ctoi_array;
- itoc_p = ^itoc_array;
-
- var last_ch : integer; { previous source character }
-
- count : array [ 0..no_of_chars-1 ] of ^count_array;
- { character count table }
-
- char_to_index : ctoi_p;
- index_to_char : itoc_p;
-
-
- procedure start_model;
-
- var ch, i : integer;
-
- begin
-
- { initialize tables for translating between symbol indicies }
- { and characters }
-
- new ( char_to_index );
- new ( index_to_char );
-
- for ch := 0 to no_of_chars-1 do
- begin
-
- { allocate space for array rows }
-
- new ( index_to_char^[ ch ] );
- new ( char_to_index^[ ch ] );
- new ( count[ ch ] );
-
- for i := 0 to no_of_chars-1 do
- begin
- index_to_char^[ ch ]^[ i+1 ] := chr ( i );
- char_to_index^[ ch ]^[ i ] := i + 1;
- end;
-
- { initialize character count table }
-
- for i := 1 to no_of_symbols do
- count[ ch ]^[ i ] := 0;
-
- count[ ch ]^[ 0 ] := max_count; { sentinel value for loop }
-
- end;
-
-
- { initialize frequency and cumulative frequency tables }
-
- for i := 0 to no_of_symbols do
- begin
- cum_freq[ i ] := no_of_symbols - i;
- freq[ i ] := 1;
- end;
-
- freq[ 0 ] := 0; { sentinel value for loop }
-
- last_ch := $0A; { LF assumed to precede first character }
-
- end; { start_model }
-
-
- function select_symbol;
-
- begin
-
- select_symbol := char_to_index^[ last_ch ]^[ ord(ch) ];
-
- end; { select symbol }
-
-
- function select_char;
-
- begin
-
- select_char := index_to_char^[ last_ch ]^[ symbol ];
-
- end; { select_char }
-
-
- procedure update_model;
-
- var i, k, x, y, next_ch, cum : integer;
- j : word;
-
-
- begin
-
- { if the total cumulative frequency has now reached the maximum }
- { allowed value, halve all counts ( keeping them non-zero ) }
-
- if ( cum_freq[ 0 ] = max_frequency ) then
- begin
- cum := 0;
- for i := no_of_symbols downto 0 do
- begin
- freq[ i ] := ( freq[ i ] + 1 ) div 2;
- cum_freq[ i ] := cum;
- inc ( cum, freq [ i ] );
- end;
- end;
-
- { select original index and count for this symbol }
-
- i := symbol;
- j := count[ last_ch ]^[ i ];
-
- next_ch := ord ( index_to_char^[ last_ch ]^[ i ] );
-
- { if the character has moved, exchange codes }
-
- while ( j = count[ last_ch ]^[ i-1 ] ) do
- begin
- k := ord ( index_to_char^[ last_ch ]^[ i-1 ] );
- index_to_char^[ last_ch ]^[ i ] := chr (k);
- char_to_index^[ last_ch ]^[ k ] := i;
- dec ( i );
- end;
-
- { if necessary reposition the symbol }
-
- if ( i < symbol ) then
- begin
- index_to_char^[ last_ch ]^[ i ] := chr ( next_ch );
- char_to_index^[ last_ch ]^[ next_ch ] := i;
- end;
-
- { increment frequency and character counts }
-
- inc ( freq[ i ] );
- inc ( count[ last_ch ]^[ i ] );
-
- { if character count has reached the maximum value allowed, }
- { halve all counts }
-
- if ( count[ last_ch ]^[ i ] = max_count ) then
- for x := 0 to no_of_chars-1 do
- if (count[ x ] <> NIL) then
- for y := 1 to no_of_symbols do
- count[ x ]^[ y ] := count[ x ]^[ y ] div 2;
-
- { update cumulative frequencies }
-
- while ( i > 0 ) do
- begin
- dec ( i );
- inc ( cum_freq[ i ] );
- end;
-
- last_ch := next_ch;
-
- end; { update_model }
-
-
- end. { Adaptive Dependency Model }